﻿#define _CRT_SECURE_NO_WARNINGS 1
#pragma once



#include <iostream>
#include <vector>
#include <cassert>
#include <thread>
#include <mutex>
using std::cout;
using std::endl;


static const size_t MAXBYTES = 256 * 1024;
static const size_t LISTNUMS = 208;

//管理返回的自由链表
//只提供管理，具体的内存块多大？不关心，根据后面的哈希桶映射进行表示.
class FreeList
{
public:
	void push(void* obj)
	{
		assert(obj);
		*(void**)obj = _freeList;
		_freeList = obj;
	}
	void* pop()
	{
		assert(_freeList);
		void* obj = _freeList;
		_freeList = *(void**)_freeList;
		return obj;
	}
	bool empty()
	{
		return _freeList == nullptr;
	}
private:
	void* _freeList = nullptr;
};


class sizeClass
{
private:
	static inline size_t _index(size_t bytes, size_t align_shift)
	{
		//这里的运算只是算对于某一个特定的对齐数，是第几号桶（某一段自由链表的第几个）
		//这里的bytes要减去前面的桶的bytes:
		//
		return ((bytes + (1 << align_shift) - 1) >> align_shift) - 1;
	}
	//
	static inline size_t _roundUp(size_t size, size_t alignNum)
	{
		return (size + alignNum - 1) & ~(alignNum - 1);
	}
public:
	// 整体控制在最多10%左右的内碎片浪费
	// [1,128] 8byte对齐      					freelist[0,16)
	// [128+1,1024] 16byte对齐  					freelist[16,72)
	// [1024+1,8*1024] 128byte对齐  			freelist[72,128)
	// [8*1024+1,64*1024] 1024byte对齐    		freelist[128,184)
	// [64*1024+1,256*1024] 8*1024byte对齐  	freelist[184,208)
	// 
	// -------------------------------------------------------------
	// 某一个对齐数代表是哪一段的链表，而index代表具体的是哪一个链表
	//计算是哪一个桶

	static inline size_t index(size_t bytes)
	{
		assert(bytes < MAXBYTES);
		//一个数组
		size_t group_array[4] = { 16, 56, 56, 56 };
		if (bytes <= 128)
		{
			return _index(bytes, 3);
		}
		else if (bytes <= 1024)
		{
			return _index(bytes - 128, 4) + group_array[0];
		}
		else if (bytes <= 8 * 1024)
		{
			return _index(bytes - 1024, 7) + group_array[0] + group_array[1];
		}
		else if (bytes <= 64 * 1024)
		{
			return _index(bytes = 8 * 1024, 10) + group_array[0] + group_array[1] + group_array[2];
		}
		else if (bytes <= 256 * 1024)
		{
			//到这里的内存一定是小于等于256 * 1024的，因为前面已经判断过了
			return _index(bytes - 64 * 1024, 13) + group_array[0] + group_array[1] + group_array[2] + group_array[3];
		}
		else
		{
			//给不了啊亲
			assert(false);
		}
		return -1;
	}


	//计算要分配多大的空间
	static inline size_t roundUp(size_t size)
	{
		if (size <= 128)
		{
			return _roundUp(size, 8);
		}
		else if (size <= 1024)
		{
			return _roundUp(size, 16);
		}
		else if (size <= 8 * 1024)
		{
			return _roundUp(size, 128);
		}
		else if (size <= 64 * 1024)
		{
			return _roundUp(size, 1024);
		}
		else if (size <= 256 * 1024)
		{
			return _roundUp(size, 8 * 1024);
		}
		assert(false);
		return -1;
	}
};